package com.unience.aws.monitor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;

import com.unience.aws.monitor.model.LoadInfo;
import com.unience.aws.monitor.model.MonitorEc2Instance;
import com.unience.ddns.IpHelper;
import com.unience.ec2.eclipse.config.Config;
import com.unience.ec2.eclipse.model.Ec2Instance;
import com.unience.ec2.eclipse.treeviewer.ui.MovingBoxView;
import com.unience.ec2.test.LaunchEc2InstanceTest;
import com.xerox.amazonws.ec2.KeyPairInfo;
import com.xerox.amazonws.ec2.ReservationDescription.Instance;

public class AwsMonitorThread extends Thread {

	private static Log log = LogFactory.getLog(AwsMonitorThread.class);

	private LaunchEc2InstanceTest ec2Instance;

	int numInstances = 0;

	double lastValue = 1;
	List<MonitorEc2Instance> listaInstances;

	HashMap<String, MonitorEc2Instance> instanceMap;

	List<Ec2InstancesListener> listeners;
	
	private String keyDir;

	private boolean stop = false;

	public AwsMonitorThread(String keyId, String secret, String userId, String keyDir) {
		ec2Instance = new LaunchEc2InstanceTest(keyId, secret, userId);
		instanceMap = new HashMap<String, MonitorEc2Instance>();

		listeners = new ArrayList<Ec2InstancesListener>();
		
		this.keyDir = keyDir;
	}

	public void addListener(Ec2InstancesListener listener) {
		listeners.add(listener);
	}

	public void run() {

		try {
			List<KeyPairInfo> keyPairs = ec2Instance.getEc2().describeKeyPairs(
					new ArrayList<String>());
			for (KeyPairInfo keyPairInfo : keyPairs) {
				log.debug(keyPairInfo.getKeyName());
				log.debug(keyPairInfo.getKeyMaterial());
			}
		} catch (Exception e) {
			log.error("error get KeyPairs", e);
		}

		while (!stop) {

			listaInstances = checkInstances();

			if (listaInstances != null) {
				numInstances = listaInstances.size();
			} else {
				numInstances = 0;
			}

			log.info("updating Ec2 Instances Info " + numInstances);

			
			updateListeners();

			try {
				sleep(5000);
			} catch (InterruptedException e) {

			}

		}

	}

	private void parseUptime(MonitorEc2Instance inst, String upTime) {

		final String LOADAVERAGE = "load average:";

		if ((upTime != null)) {// ) && (!upTime.isEmpty()) ) {
			int index = upTime.indexOf(LOADAVERAGE);

			String loads = upTime.substring(index + LOADAVERAGE.length());

			StringTokenizer token = new StringTokenizer(loads, ",");

			String load1M = token.nextToken();
			String load5M = token.nextToken();
			String load15M = token.nextToken();
			load15M = load15M.substring(0, load15M.length() - 1);
			LoadInfo loadInfo = inst.getMonitorInfo().getLoadInfo();
			loadInfo.setLoad1m(load1M);
			loadInfo.setLoad5m(load5M);
			loadInfo.setLoad15m(load15M);

		}

	}

	private void updateListeners() {

		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
			Ec2InstancesListener listener = (Ec2InstancesListener) iterator
					.next();

			listener.update(instanceMap.values(), listener);

		}

	}

	public void stopMonitor() {
		this.stop = true;
		try {
			this.join();
		} catch (InterruptedException e) {
			log.warn(e);
		}
	}

	private List<MonitorEc2Instance> checkInstances() {

		List<MonitorEc2Instance> ret = new ArrayList<MonitorEc2Instance>();

		try {
			List<String> instancesId = new ArrayList<String>();
			List<com.xerox.amazonws.ec2.ReservationDescription> reservationDescrp = this.ec2Instance
					.getEc2().describeInstances(instancesId);

			for (com.xerox.amazonws.ec2.ReservationDescription reserv : reservationDescrp) {
				List<Instance> instances = reserv.getInstances();

				for (Instance instance : instances) {

					StringBuffer buf = new StringBuffer();

					buf.append("InstanceId: ").append(instance.getInstanceId());
					buf.append(" DnsName").append(instance.getDnsName());
					buf.append(" State").append(instance.getState());
					buf.append(" StateCode").append(instance.getStateCode());

					buf.append(" running").append(instance.isRunning());
					MonitorEc2Instance ec2InstanceMonitor = null;

					// Si existe en InstanceMap
					if (!instanceMap.containsKey(instance.getInstanceId())) {
						log
								.debug("Adding to Map : "
										+ instance.getInstanceId());
						ec2InstanceMonitor = new MonitorEc2Instance(this.keyDir);

						ec2InstanceMonitor.setInstance(instance);
						
						ec2InstanceMonitor.setIp(IpHelper.getIp(instance
								.getDnsName()));
						ec2InstanceMonitor.setGroups(reserv.getGroups());
						

						instanceMap.put(instance.getInstanceId(),
								ec2InstanceMonitor);
					} else {
						ec2InstanceMonitor = instanceMap.get(instance
								.getInstanceId());

						ec2InstanceMonitor.setInstance(instance);
					}

					ret.add(ec2InstanceMonitor);

					log.info(buf.toString());

				}
			}
		} catch (com.xerox.amazonws.ec2.EC2Exception e) {
			log.error(e.getMessage());
		}

		return ret;
	}

}
